/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.extensions.modules.java14print;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.PageDefinition;
import org.pentaho.reporting.engine.classic.core.ReportProcessingException;
import org.pentaho.reporting.engine.classic.core.event.ReportProgressListener;
import org.pentaho.reporting.engine.classic.core.modules.gui.print.PrintUtil;
import org.pentaho.reporting.engine.classic.core.modules.output.pageable.graphics.PrintReportProcessor;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.ServiceUI;
import javax.print.SimpleDoc;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.Size2DSyntax;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaName;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
/**
* Creation-Date: 05.09.2005, 19:11:47
*
* @author Thomas Morgner
*/
public class Java14PrintUtil {
private static final Log logger = LogFactory.getLog( Java14PrintUtil.class );
public static final int CONFIGURATION_VALID = 0;
public static final int CONFIGURATION_REPAGINATE = 1;
public static final int CONFIGURATION_SHOW_DIALOG = 2;
private static final double POINTS_PER_INCH = 72.0;
private Java14PrintUtil() {
}
/**
* This tests, whether the given attribute set defines the same page properties as the given JFreeReport object.
* <p/>
* While showing the print dialog, the user has the chance to alter the page format of the print job. When that
* happens, we have to repaginate the whole report, which may render the users page range input invalid. In that case,
* we will have to redisplay the dialog.
*
* @param attributes
* @param report
* @return
*/
public static int isValidConfiguration( final PrintRequestAttributeSet attributes, final MasterReport report ) {
final PrintRequestAttributeSet reportAttributes = copyConfiguration( null, report );
// now, compare that minimal set with the given attribute collection.
final Attribute[] printAttribs = reportAttributes.toArray();
boolean invalidConfig = false;
for ( int i = 0; i < printAttribs.length; i++ ) {
final Attribute attrib = printAttribs[i];
if ( attributes.containsValue( attrib ) == false ) {
invalidConfig = true;
break;
}
}
if ( invalidConfig == false ) {
return CONFIGURATION_VALID;
}
if ( attributes.containsKey( PageRanges.class ) ) {
return CONFIGURATION_SHOW_DIALOG;
}
return CONFIGURATION_REPAGINATE;
}
/**
* This method replaces the media definition from the given attribute set with the one found in the report itself.
* <p/>
* If no JobName is set, a default jobname will be assigned.
*
* @param attributes
* @param report
* @return
*/
public static PrintRequestAttributeSet copyConfiguration( PrintRequestAttributeSet attributes,
final MasterReport report ) {
if ( attributes == null ) {
attributes = new HashPrintRequestAttributeSet();
}
// for now, be lazy, assume that the first page is the reference
final PageDefinition pdef = report.getPageDefinition();
final PageFormat format = pdef.getPageFormat( 0 );
final Paper paper = format.getPaper();
final Media media =
MediaSize.findMedia( (float) ( paper.getWidth() / POINTS_PER_INCH ),
(float) ( paper.getHeight() / POINTS_PER_INCH ), Size2DSyntax.INCH );
attributes.add( media );
final MediaPrintableArea printableArea =
new MediaPrintableArea( (float) ( paper.getImageableX() / POINTS_PER_INCH ),
(float) ( paper.getImageableY() / POINTS_PER_INCH ),
(float) ( paper.getImageableWidth() / POINTS_PER_INCH ),
(float) ( paper.getImageableHeight() / POINTS_PER_INCH ), Size2DSyntax.INCH );
attributes.add( printableArea );
attributes.add( mapOrientation( format.getOrientation() ) );
return attributes;
}
public static PrintRequestAttributeSet copyAuxillaryAttributes( PrintRequestAttributeSet attributes,
final MasterReport report ) {
if ( attributes == null ) {
attributes = new HashPrintRequestAttributeSet();
}
if ( attributes.containsKey( JobName.class ) == false ) {
final String jobName =
report.getReportConfiguration().getConfigProperty( PrintUtil.PRINTER_JOB_NAME_KEY, report.getTitle() );
if ( jobName != null ) {
attributes.add( new JobName( jobName, null ) );
}
}
if ( attributes.containsKey( Copies.class ) == false ) {
final int numberOfCopies = PrintUtil.getNumberOfCopies( report.getReportConfiguration() );
attributes.add( new Copies( numberOfCopies ) );
}
return attributes;
}
public static PageFormat extractPageFormat( final PrintRequestAttributeSet attributeSet ) {
final Media media = (Media) attributeSet.get( Media.class );
final MediaPrintableArea printableArea = (MediaPrintableArea) attributeSet.get( MediaPrintableArea.class );
final OrientationRequested orientationRequested =
(OrientationRequested) attributeSet.get( OrientationRequested.class );
final MediaSize mediaSize = lookupMediaSize( media );
if ( mediaSize == null ) {
logger.warn( "Unknown media encountered, unable to compute page sizes." );
}
final PageFormat pageFormat = new PageFormat();
pageFormat.setPaper( createPaper( mediaSize, printableArea ) );
if ( OrientationRequested.PORTRAIT.equals( orientationRequested ) ) {
pageFormat.setOrientation( PageFormat.PORTRAIT );
} else if ( OrientationRequested.LANDSCAPE.equals( orientationRequested ) ) {
pageFormat.setOrientation( PageFormat.LANDSCAPE );
} else if ( OrientationRequested.REVERSE_LANDSCAPE.equals( orientationRequested ) ) {
pageFormat.setOrientation( PageFormat.REVERSE_LANDSCAPE );
} else if ( OrientationRequested.REVERSE_PORTRAIT.equals( orientationRequested ) ) {
pageFormat.setOrientation( PageFormat.PORTRAIT );
}
return pageFormat;
}
private static Paper createPaper( final MediaSize mediaSize, final MediaPrintableArea printableArea ) {
final Paper paper = new Paper();
if ( mediaSize != null ) {
paper.setSize( mediaSize.getX( Size2DSyntax.INCH ) * POINTS_PER_INCH, mediaSize.getY( Size2DSyntax.INCH )
* POINTS_PER_INCH );
}
if ( printableArea != null ) {
paper.setImageableArea( printableArea.getX( Size2DSyntax.INCH ) * POINTS_PER_INCH, printableArea
.getY( Size2DSyntax.INCH )
* POINTS_PER_INCH, printableArea.getWidth( Size2DSyntax.INCH ) * POINTS_PER_INCH, printableArea
.getHeight( Size2DSyntax.INCH )
* POINTS_PER_INCH );
}
return paper;
}
private static MediaSize lookupMediaSize( final Media media ) {
if ( media instanceof MediaSizeName ) {
return MediaSize.getMediaSizeForName( (MediaSizeName) media );
} else if ( media instanceof MediaName ) {
if ( media.equals( MediaName.ISO_A4_TRANSPARENT ) || media.equals( MediaName.ISO_A4_WHITE ) ) {
return MediaSize.getMediaSizeForName( MediaSizeName.ISO_A4 );
} else if ( media.equals( MediaName.NA_LETTER_TRANSPARENT ) || media.equals( MediaName.NA_LETTER_WHITE ) ) {
return MediaSize.getMediaSizeForName( MediaSizeName.NA_LETTER );
}
}
return null;
}
private static OrientationRequested mapOrientation( final int orientation ) {
switch ( orientation ) {
case PageFormat.LANDSCAPE:
return OrientationRequested.LANDSCAPE;
case PageFormat.REVERSE_LANDSCAPE:
return OrientationRequested.REVERSE_LANDSCAPE;
case PageFormat.PORTRAIT:
return OrientationRequested.PORTRAIT;
default:
throw new IllegalArgumentException( "The given value is no valid PageFormat orientation." );
}
}
public static void printDirectly( final MasterReport report, PrintService printService ) throws PrintException,
ReportProcessingException {
// with that method we do not use the PrintService UI ..
// it is up to the user to supply a valid print service that
// supports the Pageable printing.
if ( printService == null ) {
printService = lookupPrintService();
} else {
if ( printService.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PAGEABLE ) == false ) {
throw new PrintException( "The print service implementation does not support the Pageable Flavor." );
}
}
PrintRequestAttributeSet attributes = Java14PrintUtil.copyConfiguration( null, report );
attributes = Java14PrintUtil.copyAuxillaryAttributes( attributes, report );
final PrintReportProcessor reportPane = new PrintReportProcessor( report );
final DocPrintJob job = printService.createPrintJob();
final SimpleDoc document = new SimpleDoc( reportPane, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null );
try {
job.print( document, attributes );
} finally {
reportPane.close();
}
}
private static PrintService lookupPrintService() throws PrintException {
final PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
if ( defaultService != null && defaultService.isDocFlavorSupported( DocFlavor.SERVICE_FORMATTED.PAGEABLE ) ) {
return defaultService;
}
final PrintService printService;
final PrintService[] services = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null );
if ( services.length == 0 ) {
throw new PrintException( "Unable to find a matching print service implementation." );
}
printService = services[0];
return printService;
}
public static boolean print( final MasterReport report ) throws PrintException, ReportProcessingException {
return print( report, null );
}
public static boolean print( final MasterReport report, final ReportProgressListener progressListener )
throws PrintException, ReportProcessingException {
final PrintService[] services = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PAGEABLE, null );
if ( services.length == 0 ) {
throw new PrintException( "Unable to find a matching print service implementation." );
}
PrintRequestAttributeSet attributes = Java14PrintUtil.copyConfiguration( null, report );
attributes = Java14PrintUtil.copyAuxillaryAttributes( attributes, report );
final PrintService service =
ServiceUI.printDialog( null, 50, 50, services, lookupPrintService(), DocFlavor.SERVICE_FORMATTED.PAGEABLE,
attributes );
if ( service == null ) {
return false;
}
final PrintReportProcessor reportPane = new PrintReportProcessor( report );
if ( progressListener != null ) {
reportPane.addReportProgressListener( progressListener );
}
try {
reportPane.fireProcessingStarted();
final DocPrintJob job = service.createPrintJob();
final SimpleDoc document = new SimpleDoc( reportPane, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null );
job.print( document, attributes );
} finally {
reportPane.fireProcessingFinished();
reportPane.close();
if ( progressListener != null ) {
reportPane.removeReportProgressListener( progressListener );
}
}
return true;
}
}